package org.mklink.service.impl;

import cn.hutool.core.util.StrUtil;
import org.mklink.domain.MkLink;
import org.mklink.enums.ControlEnum;
import org.mklink.service.IMkLinkService;
import org.mklink.util.AlertUtil;
import org.mklink.util.FileUtil;
import org.mklink.util.LanguageUtil;
import org.mklink.util.UI;

import java.io.File;
import java.io.IOException;

/**
 * 软链接
 * @Author: wyx
 * @Date: 2023/8/20 19:05
 */
public abstract class MkLinkService implements IMkLinkService {
    
    /**
     * 创建链接
     * @param link
     * @return
     */
    @Override
public final boolean mkLink(MkLink link) {
    if (StrUtil.isEmpty(link.getSourcePath())) {
        return handleFailure(LanguageUtil.getString("error.source.path.empty"));
    }
    if (StrUtil.isEmpty(link.getTargetPath())) {
        return handleFailure(LanguageUtil.getString("error.target.path.empty"));
    }
    if (link.getTargetPath().equals(link.getSourcePath())) {
        return handleFailure(LanguageUtil.getString("error.path.same"));
    }

    // 判断源路径是否已经是软链接
    try {
        if (FileUtil.isLink(new File(link.getSourcePath()))) {
            return handleFailure(LanguageUtil.getString("error.source.already.link"));
        }
    } catch (IOException e) {
        // 可以考虑添加日志记录：logger.warn("检查源路径是否为软链接时发生异常", e);
        return handleFailure(LanguageUtil.getString("error.source.link.check.failed"));
    }

    // 判断目标路径是否存在
    if (!FileUtil.exist(link.getTargetPath())) {
        if (FileUtil.mkdir(link.getTargetPath())==null) {
            return handleFailure(LanguageUtil.getString("error.target.create.failed"));
        }
    }
    
    // 判断目标路径是否已经是软链接
    try {
        if (FileUtil.isLink(new File(link.getTargetPath()))) {
            return handleFailure(LanguageUtil.getString("error.target.already.link"));
        }
    } catch (IOException e) {
        // 可以考虑添加日志记录：logger.warn("检查目标路径是否为软链接时发生异常", e);
        return handleFailure(LanguageUtil.getString("error.target.link.check.failed"));
    }

    // 判断是否正确的路径盘符
    if (!FileUtil.validPath(link.getTargetPath())) {
        return handleFailure(LanguageUtil.getString("error.target.path.invalid"));
    }
    UI.clearListViewItem();
    return doMkLink(link);
}

private boolean handleFailure(String message) {
    AlertUtil.information(message);
    UI.setDisable(false);
    UI.updateLabelText(ControlEnum.BTN_LINK, LanguageUtil.getString("button.link"));
    UI.addListViewItem(ControlEnum.LIST_VIEW_SUCCESS, message);
    return false;
}

    
    /**
     * 取消链接
     * @param link
     * @return
     */
    @Override
public final boolean unMkLink(MkLink link){
    if(StrUtil.isEmpty(link.getSourcePath())){
        handleUnlinkError(LanguageUtil.getString("error.unlink.source.empty"));
        return false;
    }
    
    try {
        if(!FileUtil.isLink(new File(link.getSourcePath()))){
            handleUnlinkError(LanguageUtil.getString("error.source.not.link"));
            return false;
        }
    }catch (IOException e){
        handleUnlinkError(LanguageUtil.getString("error.source.not.link"));
        return false;
    }
    UI.clearListViewItem();
    return doUnMkLink(link);
}

private void handleUnlinkError(String message) {
    AlertUtil.information(message);
    UI.setDisable(false);
    UI.updateLabelText(ControlEnum.BTN_UNLINK, LanguageUtil.getString("button.unlink"));
    UI.addListViewItem(ControlEnum.LIST_VIEW_SUCCESS, message);
}

    
    /**
     * 实际业务逻辑创建链接：由子类实现
     * @param link
     * @return
     */
    protected abstract boolean doMkLink(MkLink link);
    
    /**
     * 实际业务逻辑取消链接：由子类实现
     * @param link
     * @return
     */
    protected abstract boolean doUnMkLink(MkLink link);
    /**
     * 取目录的文件夹名称
     * @param path
     * @return
     */
    private String getLastPathName(String path){
        if(StrUtil.isNotEmpty(path)){
            int lastNameIndex = StrUtil.lastIndexOfIgnoreCase(path,"\\");
            String name = StrUtil.sub(path,lastNameIndex+1,StrUtil.length(path));
            return name;
        }
        return "";
    }
    
    /**
     * 根据mode获取cmd命令
     * @return
     */
    public String getCmdByMode(String sourcePath,String targetPath,String mode){
        StringBuffer sb = new StringBuffer();
        sb.append("cmd /c").append(" ");
        sb.append("mklink /").append(mode).append(" ");
        sb.append("\"").append(sourcePath).append("\"").append(" ");
        sb.append("\"").append(targetPath).append("\"");
        return sb.toString();
    }
}
